package front

import (
	"geekai/api/dto/request"
	"geekai/api/handler"
	"geekai/core"
	"geekai/core/types"
	"geekai/service"
	"geekai/service/sms"
	"geekai/utils"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"strings"
)

const CodeStorePrefix = "/verify/codes/"

type SmsHandler struct {
	handler.BaseHandler
	redis *redis.Client
	sms   *sms.ServiceManager
	smtp  *service.SmtpService
}

func NewSmsHandler(app *core.AppServer, client *redis.Client, sms *sms.ServiceManager, smtp *service.SmtpService) *SmsHandler {
	return &SmsHandler{
		BaseHandler: handler.BaseHandler{App: app},
		redis:       client,
		sms:         sms,
		smtp:        smtp,
	}
}

// SendCode godoc
// @Summary      发送短信，支持 手机号、邮箱 发送验证码
// @Description  发送短信，支持 手机号、邮箱 发送验证码
// @Tags         前台-验证码
// @Accept       json
// @Produce      json
// @Param        req   body     request.SendCodeReq  true  "验证码发送信息"
// @Success      200  {object}  types.BizVo{}
// @Router       /api/sms/send_code [post]
func (h *SmsHandler) SendCode(c *gin.Context) {
	sendCodeReq := &request.SendCodeReq{}
	if err := c.ShouldBindJSON(sendCodeReq); err != nil {
		utils.ERROR(c, types.InvalidArgs)
		return
	}
	// 生成验证码
	code := utils.RandomNumber(6)
	var err error
	if strings.Contains(sendCodeReq.Receiver, "@") { // 判断接受者是不是邮箱
		// 判断系统是否允许邮箱注册
		if !utils.Contains(h.App.SysConfig.RegisterWays, "email") {
			utils.ERROR(c, "系统已经禁止邮箱注册")
			return
		}
		// 检查邮箱后缀是否存在白名单中
		if len(h.App.SysConfig.EmailWhiteList) > 0 {
			inWhiteList := false
			for _, suffix := range h.App.SysConfig.EmailWhiteList {
				// 检查邮箱后缀是否在白名单中
				if strings.HasSuffix(sendCodeReq.Receiver, suffix) {
					inWhiteList = true
					break
				}
			}
			if !inWhiteList {
				utils.ERROR(c, "邮箱后缀不在白名单中")
				return
			}
		}
		// 发送邮件
		err = h.smtp.SendVerifyCode(sendCodeReq.Receiver, code)
	} else {
		// 手机号发送验证码
		// 判断系统是否开启了手机号注册
		if !utils.Contains(h.App.SysConfig.RegisterWays, "mobile") {
			utils.ERROR(c, "系统已禁用手机号注册！")
			return
		}
		// 手机发送验证码
		err = h.sms.GetService().SendVerifyCode(sendCodeReq.Receiver, code)
	}
	if err != nil {
		utils.ERROR(c, err.Error())
		return
	}
	// 存储验证码，等待后面注册验证
	_, err = h.redis.Set(c, CodeStorePrefix+sendCodeReq.Receiver, code, 0).Result()
	if err != nil {
		utils.ERROR(c, "验证码保存失败")
		return
	}
	if h.App.Debug {
		utils.SUCCESS(c, code)
	} else {
		utils.SUCCESS(c)
	}
}
